package com.ggb.reactive.controller.admin

import com.ggb.reactive.constant.ACTION_FAIL
import com.ggb.reactive.domain.dto.EmployeeLoginDTO
import com.ggb.reactive.domain.dto.EmployeePageQueryDTO
import com.ggb.reactive.domain.entity.Employee
import com.ggb.reactive.domain.vo.EmployeeLoginVO
import com.ggb.reactive.model.PageResult
import com.ggb.reactive.model.Result
import com.ggb.reactive.repository.EmployeeRepository
import com.ggb.reactive.service.EmployeeService
import com.ggb.reactive.service.JwtSigner
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import lombok.RequiredArgsConstructor
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Mono
import java.time.Instant

@RestController
@RequiredArgsConstructor
@RequestMapping("/admin/employee")
@Tag(name = "员工管理")
class EmployeeController(
    val employeeRepository: EmployeeRepository,
    val jwtSigner: JwtSigner,
    val password: PasswordEncoder,
    val employeeService: EmployeeService
) {

    /**
     * 登录
     */
    @Operation(summary = "登录")
    @PostMapping("/login")
    fun login(@RequestBody @Validated employeeLoginDTO: EmployeeLoginDTO): Mono<Result<EmployeeLoginVO>> {
        return Mono.just(employeeLoginDTO.username)
            .flatMap { it -> employeeRepository.findByUsername(it) }
            .doOnNext { it -> println("用户信息为： $it") }
            .filter {
                password.matches(employeeLoginDTO.password, it.password)&&it.status==1
            }
            .map {
                Result.success(
                    EmployeeLoginVO(
                        id = it.id!!,
                        userName = it.username!!,
                        name = it.name!!,
                        token = jwtSigner.generateToken(
                            it.id
                        )
                    )
                )
            }

            .onErrorResume {
                Mono.just(Result.error("密码不正确"))
            }
            .switchIfEmpty(Mono.just(Result.error("登录失败")))

    }

    /**
     * 新增员工
     */
    @Operation(summary = "新增员工")
    @PostMapping
    fun save(@RequestBody employee: Employee): Mono<Result<String>> {
        // 对密码进行加密存储
        employee.password = password.encode(employee.password)
        employee.createTime = Instant.now()
        employee.updateTime = Instant.now()
        return employeeRepository.save(employee).flatMap {
            Mono.just(Result.success<String>())
        }.onErrorResume {
            Mono.just(Result.error(ACTION_FAIL))
        }
    }

    /**
     * 分页查询
     */
    @Operation(summary = "员工分页查询")
    @GetMapping("/page")
    fun page(employeePageQueryDTO: EmployeePageQueryDTO):Mono<Result<PageResult<Employee>>> = employeeService.findEmployeeByCriteria(employeePageQueryDTO)

    //
    //{
    //    return employeeService.findEmployeeByCriteria(employeePageQueryDTO)
    // 假设EmployeePageQueryDTO中有页码和每页大小
        //val pageRequest = PageRequest.of(employeePageQueryDTO.page - 1, employeePageQueryDTO.pageSize)
        //
        //return myUserRepository.findAllByNameContains(employeePageQueryDTO.name)
        //    .map{
        //        // 过滤调
        //        it.password = "***"
        //        it
        //    }
        //    .collectList() // 将Flux<User>转换为Mono<List<User>>
        //    .map { users ->
        //        // 根据分页参数手动实现分页逻辑
        //        val start = pageRequest.offset.toInt()
        //        val end = (start + pageRequest.pageSize).coerceAtMost(users.size)
        //        val pageContent = if(start <= end) users.subList(start, end) else listOf()
        //
        //        PageImpl(pageContent, pageRequest, users.size.toLong())
        //    }
        //    .map { page ->
        //        // 将Page<User>转换为你的PageResult<User>（假设你有一个类似的结构）
        //        Result.success(PageResult(total = page.totalElements, records = page.content))
        //    }
    //}

    /**
     * 更新状态
     */
    @Operation(summary = "更新员工状态")
    @PostMapping("/status/{status}")
    fun startOrStop(@PathVariable  status: Int?, id:Long?):Mono<Result<String>>{
        //val user = User(id=id,status = status)
        //return myUserRepository.save(user)
        if (id == null) return Mono.just(Result.error("id名不能为空"))
        if (status == null) return Mono.just(Result.error("status不能为空"))
        return employeeRepository.updateStatusById(id,status,Instant.now())
            .map {
                Result.success<String>()
            }
            .onErrorResume {
                Mono.just(Result.error(ACTION_FAIL))
            }
        //return myUserRepository.findById(id)
        //    .map {
        //        it.status = status
        //        it
        //    }
        //    .flatMap {
        //        myUserRepository.save(it)
        //    }
        //    .map {
        //        Result.success<String>()
        //    }
        //    .onErrorResume {
        //        Mono.just(Result.error(ACTION_FAIL))
        //    }
    }

    /**
     * 根据id查询员工信息
     */
    @Operation(summary = "根据id查询员工信息")
    @GetMapping("/{id}")
    fun getById(@PathVariable id:Long):Mono<Result<Employee>>{
        return employeeRepository.findById(id)
            .map {
                Result.success(it)
            }
            .onErrorResume {
                Mono.just(Result.error(ACTION_FAIL))
            }
    }

    /**
     * 更新员工信息
     */
    @Operation(summary = "更新员工信息")
    @PutMapping
    fun update(@RequestBody employee: Employee):Mono<Result<String>>{
        employee.updateTime = Instant.now()
        return employeeRepository.save(employee)
            .map {
                Result.success<String>()
            }
            .onErrorResume {
                Mono.just(Result.error(ACTION_FAIL))
            }
    }

    /**
     * 退出登录
     */
    @Operation(summary = "退出登录")
    @PostMapping("/logout")
    fun logout():Mono<Result<String>>{
        return Mono.just(Result.success())
    }
}